﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Reflection;
using System.Xml;
using System.Security.Cryptography;
using Microsoft.Win32;

namespace IVTQLBH.UTILITIES
{
    public class Utility
    {
        public static string stylename = "";

        public static void SaveStyle()
        {
            try
            {
                RegistryKey regKeyAppRoot = Registry.CurrentUser.CreateSubKey("StylePMBH");
                regKeyAppRoot.SetValue("style", Utility.stylename);
            }
            catch (Exception ex)
            {
                ;
            }
        }

        public static void ReadStyle()
        {
            RegistryKey regKeyAppRoot = Registry.CurrentUser.CreateSubKey("StylePMBH");
            string mTmp = null;                               
            try
            {
                mTmp = (string)regKeyAppRoot.GetValue("style"); if (mTmp != null) { Utility.stylename = mTmp; }
            }
            catch (Exception ex)
            {
                ;
            }
        }

        public static DataTable LINQToDataTable<T>(IEnumerable<T> varlist)
        {
            DataTable dtReturn = new DataTable();
            PropertyInfo[] oProps = null;
            if (varlist == null) return dtReturn;
            foreach (T rec in varlist)
            {
                if (oProps == null)
                {
                    oProps = ((Type)rec.GetType()).GetProperties();
                    foreach (PropertyInfo pi in oProps)
                    {
                        Type colType = pi.PropertyType;
                        if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition()
                        == typeof(Nullable<>)))
                        {
                            colType = colType.GetGenericArguments()[0];
                        }
                        dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
                    }
                }
                DataRow dr = dtReturn.NewRow();
                foreach (PropertyInfo pi in oProps)
                {
                    dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue
                    (rec, null);
                }
                dtReturn.Rows.Add(dr);
            }
            return dtReturn;
        }

        public static DataTable SelectDistinct(DataTable SourceTable, string FieldName)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add(FieldName, SourceTable.Columns[FieldName].DataType);

            object LastValue = null;
            foreach (DataRow dr in SourceTable.Select("", FieldName))
            {
                if (LastValue == null || !(ColumnEqual(LastValue, dr[FieldName])))
                {
                    LastValue = dr[FieldName];
                    dt.Rows.Add(new object[] { LastValue });
                }
            }
            return dt;
        }

        public static DataTable SelectDistinctAddColumn(DataTable SourceTable, string FieldName, string FieldName2)
        {
            try
            {
                DataTable dt = new DataTable();
                dt.Columns.Add(FieldName, SourceTable.Columns[FieldName].DataType);
                dt.Columns.Add(FieldName2, SourceTable.Columns[FieldName2].DataType);

                object LastValue = null;
                object FileldValue2 = null;
                foreach (DataRow dr in SourceTable.Select("", FieldName))
                {
                    if (LastValue == null || !(ColumnEqual(LastValue, dr[FieldName])))
                    {
                        LastValue = dr[FieldName];
                        FileldValue2 = dr[FieldName2];
                        dt.Rows.Add(new object[] { LastValue, FileldValue2 });
                    }
                }
                return dt;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        private static bool ColumnEqual(object A, object B)
        {
            // Compares two values to see if they are equal. Also compares DBNULL.Value.
            // Note: If your DataTable contains object fields, then you must extend this
            // function to handle them in a meaningful way if you intend to group on them.

            if (A == DBNull.Value && B == DBNull.Value) //  both are DBNull.Value
                return true;
            if (A == DBNull.Value || B == DBNull.Value) //  only one is DBNull.Value
                return false;
            return (A.Equals(B));  // value type standard comparison
        }

        public static bool ContentDonVi(List<int> list, int x)
        {
            foreach (int i in list)
            {
                if (i == x) return true;
            }
            return false;
        }

        private readonly static Random _rng = new Random();
        private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";

        public static string RandomString(int size)
        {
            char[] buffer = new char[size];

            for (int i = 0; i < size; i++)
            {
                buffer[i] = _chars[_rng.Next(_chars.Length)];
            }
            return new string(buffer);
        }

        public static string GetMD5Hash(string input)
        {
            MD5CryptoServiceProvider x = new MD5CryptoServiceProvider();
            byte[] bs = Encoding.UTF8.GetBytes(input);
            bs = x.ComputeHash(bs);
            System.Text.StringBuilder s = new StringBuilder();
            foreach (byte b in bs)
            {
                s.Append(b.ToString("x2").ToLower());
            }
            string password = s.ToString();
            return password;
        }

        public static string CreateMD5Hash(string input)
        {
            // Use input string to calculate MD5 hash
            MD5 md5 = MD5.Create();
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
            byte[] hashBytes = md5.ComputeHash(inputBytes);

            // Convert the byte array to hexadecimal string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hashBytes.Length; i++)
            {
                sb.Append(hashBytes[i].ToString("x2"));
                // To force the hex string to lower-case letters instead of
                // upper-case, use he following line instead:
                // sb.Append(hashBytes[i].ToString("x2")); 
            }
            return sb.ToString();
        }

        public static readonly SHA1CryptoServiceProvider PWD_CRYPTO = new SHA1CryptoServiceProvider();
        public static string HashPassword(string password)
        {
            if (password == null) throw new ArgumentNullException("password");

            byte[] encryptedBytes = PWD_CRYPTO.ComputeHash(Encoding.UTF8.GetBytes(password));

            StringBuilder sb = new StringBuilder();
            foreach (byte b in encryptedBytes) sb.AppendFormat("{0:x2}", b);

            return sb.ToString();
        }

    }

    public static class EnumerableEx
    {
        //// Then later in the code
        //List<Stock> res = src.uniqueBy( elt => elt.Type ).ToList()
        //    List<Stock> kitchenAppliances =
        //(from obj in stock
        // where obj.Type == "Kitchen Appliance"
        // select obj).ToList();
        public static IEnumerable<tSource> uniqueBy<tSource, tKey>(this IEnumerable<tSource> src, Func<tSource, tKey> keySelecta)
        {
            HashSet<tKey> res = new HashSet<tKey>();
            foreach (tSource e in src)
            {
                tKey k = keySelecta(e);
                if (res.Contains(k))
                    continue;
                res.Add(k);
                yield return e;
            }
        }

    }

}
